package com.duzq;

import java.sql.*;

public class JDBC {
    public static void main(String[] args) {
        try {
            // 1. 加载驱动
            System.out.println("1. 加载驱动");
            Class.forName("com.mysql.jdbc.Driver");

            // 2. 创建链接
            System.out.println("2. 创建链接");
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/test",
                    "root",
                    "root1234");

            /*
                要执行SQL语句，必须获得java.sql.Statement实例，Statement实例分为以下3 种类型：
                执行静态SQL语句。通常通过 Statement 实例实现。
                执行动态SQL语句。通常通过 PreparedStatement 实例实现。
                执行数据库存储过程。通常通过 CallableStatement 实例实现。
            */
            // 3. 创建预处理查询对象
            System.out.println("3. 创建预处理查询对象");
            String sql = "SELECT id, ORDER_CODE orderCode from t_order WHERE id = ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            // TODO: 为什么 PreparedStatement 可以解决SQL注入的问题呢？
            // PreparedStatement.setString() 的时候 调用了ClientPreparedQueryBindings.setString()，对特殊字符进行了转译处理
            // 例如特殊字符：'
            // https://blog.csdn.net/lisehouniao/article/details/51523497
            // https://blog.csdn.net/u011649691/article/details/83054651
            ps.setString(1, "0087eecc-50e0-4552-9be3-9ee60d6c3350 ' or 1 = 1");
            // 以上SQL语句会变成：SELECT id, ORDER_CODE orderCode from t_order WHERE id = '0087eecc-50e0-4552-9be3-9ee60d6c3350 \' or 1 = 1'
            // 从而解决了SQL注入问题

            // 4. 处理返回结果
            System.out.println("4. 处理返回结果");
            ResultSet resultSet = ps.executeQuery();
            if (resultSet != null) {
                while (resultSet.next()) {
                    System.out.println(
                            "ID：" + resultSet.getString("id")
                            + "    "
                            + "orderCode：" + resultSet.getString("orderCode")
                    );
                }
            }

            // 5. 关闭数据库链接
            System.out.println("5. 关闭数据库链接");
            ps.close();
            conn.close();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }

    }
}
